package com.wangxiaonan.berry.handler;

import com.wangxiaonan.berry.exception.ParamValidationException;
import com.wangxiaonan.berry.exception.PermissionDeniedException;
import com.wangxiaonan.berry.exception.ResourceNotFoundException;
import com.wangxiaonan.berry.exception.SystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

/**
 * 统一异常处理
 *
 * @Author: wangxiaonan
 * @Date: 2018/12/28
 **/
@RestControllerAdvice(annotations = {ResponseBody.class})
public class ControllerAdviceHandler {

    private static final Logger logger = LoggerFactory.getLogger(ControllerAdviceHandler.class);

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = Exception.class)
    public ResponseWrapper exceptionHandle(Exception e) {
        ResponseWrapper responseWrapper = new ResponseWrapper();
        logger.error("[SystemException]Exception:", e);
        return responseWrapper.fail(HttpStatus.INTERNAL_SERVER_ERROR, "System Error, please try again later!");
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = SystemException.class)
    public ResponseWrapper systemExceptionHandle(Exception e) {
        ResponseWrapper responseWrapper = new ResponseWrapper();
        logger.error("[SystemException]Exception:", e);
        return responseWrapper.fail(HttpStatus.INTERNAL_SERVER_ERROR,
                "System Error, please try again later! Message:%s", e.getMessage());
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    public ResponseWrapper MethodArgumentTypeMismatchExceptionHandle(Exception e) {
        logger.error("Bad request, Please check request parameter!", e);
        return new ResponseWrapper().fail(HttpStatus.BAD_REQUEST, "Bad request, Please check request parameter!");
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = {ParamValidationException.class})
    public ResponseWrapper paramValidationExceptionHandle(Exception e) {
        ResponseWrapper responseWrapper = new ResponseWrapper();
        logger.error("[ParamValidationException]Exception:", e);
        return responseWrapper
                .fail(HttpStatus.BAD_REQUEST, "Parameter validation failure! Message:%s" + e.getMessage());
    }

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(value = {PermissionDeniedException.class})
    public ResponseWrapper permissionDeniedExceptionHandle(Exception e) {
        ResponseWrapper responseWrapper = new ResponseWrapper();
        logger.error("[PermissionDeniedException]Exception:", e);
        return responseWrapper.fail(HttpStatus.UNAUTHORIZED, "Permission Denied!");
    }

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(value = {ResourceNotFoundException.class})
    public ResponseWrapper resourceNotFoundExceptionHandle(Exception e) {
        ResponseWrapper responseWrapper = new ResponseWrapper();
        logger.error("[ResourceNotFoundException]Exception:", e);
        return responseWrapper.fail(HttpStatus.NOT_FOUND, "Resource not found! Message:%s", e.getMessage());
    }
}
